package com.learn.core.controller.manager;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.learn.common.annotation.Log;
import com.learn.common.annotation.UserLoginToken;
import com.learn.common.enums.BusinessType;
import com.learn.common.enums.OperatorType;
import com.learn.common.enums.ResultEnum;
import com.learn.common.utils.*;
import com.learn.common.utils.file.FileUtils;
import com.learn.common.utils.poi.ExcelUtils;
import com.learn.common.utils.result.CommonResult;
import com.learn.core.domain.LDetails;
import com.learn.core.domain.LOrganization;
import com.learn.core.domain.LRole;
import com.learn.core.domain.LUser;
import com.learn.core.domain.view.UserDetailsGather;
import com.learn.core.dto.LUserDTO;
import com.learn.core.service.*;
import com.learn.framework.enums.ErrorCodeEnum;
import com.learn.framework.utils.ApiAssert;
import com.learn.framework.web.controller.WebController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @auther CodeGenerator
 * @create 2021-03-08 22:50:00
 * @describe 用户表前端控制器
 */
@Api("用户管理")
@RestController
@RequestMapping("/manager/user")
@CrossOrigin
public class LUserController extends WebController<LUser> {

    @Autowired
    private ILUserService ilUserService;
    @Autowired
    private IUserDetailsGatherService iUserDetailsGatherService;
    @Autowired
    private ILDetailsService ilDetailsService;
    @Autowired
    private ILOrganizationService ilOrganizationService;
    @Autowired
    private ILRoleService ilRoleService;

    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

    //列表
    @ApiOperation(value = "获取列表")
    @UserLoginToken
    @PostMapping("/list")
    public PageResult<LUser> list(@RequestBody LUserDTO lUserDTO){
        try {
            if (lUserDTO==null||lUserDTO.getPage()==null||lUserDTO.getRows()==null){
                return new PageResult<>(null, null, ResultEnum.ERROR);
            }
            PageHelper.startPage(lUserDTO.getPage(),lUserDTO.getRows());
            QueryWrapper<UserDetailsGather> queryWrapper = new QueryWrapper<>();
            if(StringUtils.isNotEmpty(lUserDTO.getMobile()))
                queryWrapper.eq("mobile",lUserDTO.getMobile());
            if(StringUtils.isNotEmpty(lUserDTO.getUsername()))
                queryWrapper.like("user_name",lUserDTO.getUsername());
            if(StringUtils.isNotEmpty(lUserDTO.getStutes()))
                queryWrapper.eq("stutes",lUserDTO.getStutes());
            if(StringUtils.isNotEmpty(lUserDTO.getSex()))
                queryWrapper.eq("sex",lUserDTO.getSex());
            if(StringUtils.isNotEmpty(lUserDTO.getName()))
                queryWrapper.like("name",lUserDTO.getName());
            if(StringUtils.isNotEmpty(lUserDTO.getOrganizationId()))
                queryWrapper.in("organization_id", lUserDTO.getOrganizationId());
            Page<UserDetailsGather> lUsers = (Page<UserDetailsGather>)iUserDetailsGatherService.list(queryWrapper);
            if (CollectionUtils.isEmpty(lUsers)) {
                return new PageResult<>(null, null, ResultEnum.NOT_EEIST);
            }
            for (UserDetailsGather userDetailsGather : lUsers) {
                LOrganization lOrganization = ilOrganizationService.getById(userDetailsGather.getOrganizationId());
                if(null != lOrganization)
                    userDetailsGather.setOrganizationName(lOrganization.getOrganizationName());
                LRole lRole = ilRoleService.getById(userDetailsGather.getRoleId());
                if(null != lRole)
                    userDetailsGather.setRoleName(lRole.getRoleName());
            }
            // 返回
            return new PageResult(lUsers.getTotal(), lUsers, ResultEnum.SUCCESS);
        }catch (Exception e){
            e.printStackTrace();
            return new PageResult(null,null,ResultEnum.ERROR);
        }
    }

    //用户个人信息
    @ApiOperation(value = "用户个人信息")
    @UserLoginToken
    @GetMapping("/info")
    public CommonResult<Object> info( @RequestParam("id")String userId){
        try {
            if (userId==null){
                return (CommonResult) ResultUtil.error(ResultEnum.LOAD_ERROR);
            }
            QueryWrapper<UserDetailsGather> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id",userId);
            UserDetailsGather lUsers = iUserDetailsGatherService.getOne(queryWrapper);
            // 返回
            LOrganization lOrganization = ilOrganizationService.getById(lUsers.getOrganizationId());
            if(null != lOrganization)
                lUsers.setOrganizationName(lOrganization.getOrganizationName());
            LRole lRole = ilRoleService.getById(lUsers.getRoleId());
            if(null != lRole)
                lUsers.setRoleName(lRole.getRoleName());
            return (CommonResult)ResultUtil.success(ResultEnum.SUCCESS,lUsers);
        }catch (Exception e){
            e.printStackTrace();
            return (CommonResult)ResultUtil.error(ResultEnum.ERROR);
        }
    }

    //添加
    @ApiOperation(value = "添加")
    @PostMapping("/add")
    @UserLoginToken
    @Log(title = "添加用户列表", businessType = BusinessType.INSERT, operatorType = OperatorType.SYSTEM)
    public CommonResult<Object> register(@RequestBody UserDetailsGather userDetailsGather){
        try {
            if(userDetailsGather==null){
                return (CommonResult) ResultUtil.error(ResultEnum.ERROR);
            }
            if(StringUtils.isNotEmpty(userDetailsGather.getUserName())){
                QueryWrapper<LUser> queryWrapper = new QueryWrapper<LUser>();
                queryWrapper.eq("user_name", userDetailsGather.getUserName());
                if(ilUserService.getOne(queryWrapper)!=null) return (CommonResult) ResultUtil.error(ResultEnum.ACCOUNT_EXIST);
            }else{
                return (CommonResult) ResultUtil.error(ResultEnum.NOT_ACCOUNT);
            }
            if(StringUtils.isEmpty(userDetailsGather.getPassword()))
                return (CommonResult) ResultUtil.error(ResultEnum.NOT_PASSWORD);
            if(StringUtils.isEmpty(userDetailsGather.getSex()))
                return (CommonResult) ResultUtil.error(ResultEnum.NOT_TEACHER_SEX);
            if(StringUtils.isEmpty(userDetailsGather.getOrganizationId()))
                return (CommonResult) ResultUtil.error(ResultEnum.NOT_ORG_ID);
            if(StringUtils.isEmpty(userDetailsGather.getBirthTime()))
                return (CommonResult) ResultUtil.error(ResultEnum.NOT_TIME_BIRTH);
            if(StringUtils.isNotEmpty(userDetailsGather.getMobile())){
                QueryWrapper<LUser> queryWrapper = new QueryWrapper<LUser>();
                queryWrapper
                        .eq("mobile", userDetailsGather.getMobile());
                if(ilUserService.getOne(queryWrapper)!=null) return (CommonResult) ResultUtil.error(ResultEnum.MOBILE_EXIST);
            }else{
                return  (CommonResult) ResultUtil.error(ResultEnum.NOT_MOBILE);
            }
            LDetails lDetails = new LDetails();
            lDetails.setName(userDetailsGather.getName());
            lDetails.setOrganizationId(userDetailsGather.getOrganizationId());
            lDetails.setSex(userDetailsGather.getSex());
            lDetails.setBirthTime(format.format(userDetailsGather.getBirthTime()));
            lDetails.setEntryTime(userDetailsGather.getEntryTime());
            lDetails.setCardId(userDetailsGather.getCardId());
            lDetails.setNation(userDetailsGather.getNation());
            lDetails.setRoleId(userDetailsGather.getRoleId());
            lDetails.setEducationId(userDetailsGather.getEducationId());
            lDetails.setCreateTime(new Date());
            if(ilDetailsService.save(lDetails)){
                LUser luser = new LUser();
                luser.setDetailsId(lDetails.getDetailsId());
                luser.setUserName(userDetailsGather.getUserName());
                luser.setPassword(Md5Utils.hash(userDetailsGather.getPassword()));
                luser.setMobile(userDetailsGather.getMobile());
                luser.setEmail(userDetailsGather.getEmail());
                luser.setStutes(userDetailsGather.getStutes());
                luser.setCreateTime(new Date());
                if(ilUserService.save(luser)){
                    return (CommonResult)ResultUtil.success(ResultEnum.SUCCESS);
                }
            }
        }catch (Exception e){
            return (CommonResult)ResultUtil.error(ResultEnum.ERROR);
        }
        return  (CommonResult)ResultUtil.error(ResultEnum.ERROR);
    }

    //更新
    @ApiOperation(value = "更新")
    @PostMapping("/edit")
    @UserLoginToken
    @Log(title = "更新用户列表", businessType = BusinessType.UPDATE, operatorType = OperatorType.SYSTEM)
    public CommonResult<Object> edit(@RequestBody UserDetailsGather userDetailsGather) {
        if(userDetailsGather!=null){
            // TODO 修改用户信息
            if(StringUtils.isEmpty(userDetailsGather.getUserId()))
                return (CommonResult)ResultUtil.error(ResultEnum.ERROR);
            if(StringUtils.isNotEmpty(userDetailsGather.getUserName())) {
                QueryWrapper<LUser> queryUser = new QueryWrapper<>();
                queryUser.eq("user_name", userDetailsGather.getUserName());
                queryUser.eq("user_id", userDetailsGather.getUserId());
                LUser isUsername = ilUserService.getOne(queryUser);
                if (null != isUsername && !isUsername.getUserId().equals(userDetailsGather.getUserId()))
                    return (CommonResult) ResultUtil.error(ResultEnum.ACCOUNT_EXIST);
            }
            QueryWrapper<LUser> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id",userDetailsGather.getUserId());
            LUser lUser = ilUserService.getOne(queryWrapper);
            if(null != lUser){
                // 修改用户详情
                LDetails lDetails = new LDetails();
                lDetails.setDetailsId(lUser.getDetailsId());
                if(StringUtils.isNotEmpty(userDetailsGather.getNation()))
                    lDetails.setNation(userDetailsGather.getNation());
                if(StringUtils.isNotEmpty(userDetailsGather.getBirthTime()))
                    lDetails.setBirthTime(format.format(userDetailsGather.getBirthTime()));
                if(StringUtils.isNotEmpty(userDetailsGather.getOrganizationId()));
                    lDetails.setOrganizationId(userDetailsGather.getOrganizationId());
                if(StringUtils.isNotEmpty(userDetailsGather.getName()))
                    lDetails.setName(userDetailsGather.getName());
                if(StringUtils.isNotEmpty(userDetailsGather.getSex()))
                    lDetails.setSex(userDetailsGather.getSex());
                if(StringUtils.isNotEmpty(userDetailsGather.getEntryTime()))
                    lDetails.setEntryTime(userDetailsGather.getEntryTime());
                if(StringUtils.isNotEmpty(userDetailsGather.getCardId()))
                    lDetails.setCardId(userDetailsGather.getCardId());
                if(StringUtils.isNotEmpty(userDetailsGather.getRoleId()))
                    lDetails.setRoleId(userDetailsGather.getRoleId());
                lDetails.setUpdateTime(new Date());
                ilDetailsService.updateById(lDetails);
                // 修改用户基本信息
                LUser user = new LUser();
                user.setUserId(userDetailsGather.getUserId());
                if(StringUtils.isNotEmpty(userDetailsGather.getUserName()))
                    user.setUserName(userDetailsGather.getUserName());
                if(StringUtils.isNotEmpty(userDetailsGather.getEmail()))
                    user.setEmail(userDetailsGather.getEmail());
                if(StringUtils.isNotEmpty(userDetailsGather.getMobile()))
                    user.setMobile(userDetailsGather.getMobile());
                if(StringUtils.isNotEmpty(userDetailsGather.getStutes()))
                    user.setStutes(userDetailsGather.getStutes());
                if(StringUtils.isNotEmpty(userDetailsGather.getPassword()))
                    user.setPassword(Md5Utils.hash(userDetailsGather.getPassword()));
                if(ilUserService.updateById(user)){
                    return (CommonResult)ResultUtil.success(ResultEnum.SUCCESS);
                }
            }
        }
        return (CommonResult)ResultUtil.error(ResultEnum.ERROR);
    }

    //删除用户
    @ApiOperation(value = "删除用户")
    @GetMapping("/del")
    @UserLoginToken
    public CommonResult<Object> del(@RequestParam("id") String id) {
        if(id!=null){
            LUser user = ilUserService.getById(id);
            if(ilDetailsService.removeById(user.getDetailsId())){
                ilUserService.removeById(id);
                return (CommonResult)ResultUtil.success(ResultEnum.SUCCESS);
            }
        }
        return (CommonResult)ResultUtil.error(ResultEnum.ERROR);
    }

    //更新密码
    @ApiOperation(value = "更新密码")
    @PostMapping("/password")
    @UserLoginToken
    public CommonResult<Object> password(@RequestBody LUser lUser) {
        if(lUser!=null){
            if(StringUtils.isEmpty(lUser.getUserId()))
                return (CommonResult) ResultUtil.error(ResultEnum.LOAD_ERROR);
            lUser.setPassword(Md5Utils.hash(lUser.getPassword()));
            if(ilUserService.updateById(lUser)){
                return (CommonResult)ResultUtil.success(ResultEnum.SUCCESS);
            }
        }
        return (CommonResult)ResultUtil.error(ResultEnum.ERROR);
    }

    //重置密码
    @ApiOperation(value = "重置密码")
    @GetMapping("/reset")
    @UserLoginToken
    public CommonResult<Object> reset(@RequestParam("userId")Integer userId) {
        if(StringUtils.isEmpty(userId))
            return (CommonResult) ResultUtil.error(ResultEnum.LOAD_ERROR);
        LUser lUser = new LUser();
        lUser.setUserId(userId);
        lUser.setPassword(Md5Utils.hash("123456"));
        if(ilUserService.updateById(lUser)){
            return (CommonResult)ResultUtil.success(ResultEnum.SUCCESS);
        }
        return (CommonResult)ResultUtil.error(ResultEnum.ERROR);
    }

    //TODO 用户导入
    @ApiOperation(value = "用户导入")
    @PostMapping("/uploadUserExcel")
    @UserLoginToken
    public CommonResult<Object> uploadUserExcel(@RequestParam MultipartFile file) {
        String fileName = file.getOriginalFilename();
        int one = fileName.lastIndexOf(".");
        String Suffix = fileName.substring((one+1),fileName.length());
        if (!"xls".equals(Suffix) && !"xlsx".equals(Suffix)) {
            return (CommonResult)ResultUtil.error(ResultEnum.FILE_FORMAT_ERROR);
        }
        ExcelUtils excelUtils = new ExcelUtils(UserDetailsGather.class);
        try {
            List<UserDetailsGather> list = excelUtils.importExcel(file.getInputStream());
            for (UserDetailsGather userDetailsGather : list) {
                String organName = userDetailsGather.getOrganizationName();
                String [] organArr = organName.split(",");
                Integer id = null;
                for (String str : organArr) {
                    QueryWrapper<LOrganization> lOrganizationQueryWrapper = new QueryWrapper<>();
                    lOrganizationQueryWrapper.eq("organization_name",str);
                    List<LOrganization> lOrganizationList = ilOrganizationService.list(lOrganizationQueryWrapper);
                    if(lOrganizationList.size() > 0){
                        id = lOrganizationList.get(0).getOrganizationId();
                    }
                }
                userDetailsGather.setOrganizationId(id);
            }
            for (UserDetailsGather userDetailsGather : list) {
                LDetails lDetails = new LDetails();
                lDetails.setName(userDetailsGather.getName());
                lDetails.setOrganizationId(userDetailsGather.getOrganizationId());
                lDetails.setSex(userDetailsGather.getSex());
                lDetails.setBirthTime(format.format(userDetailsGather.getBirthTime()));
                lDetails.setEntryTime(userDetailsGather.getEntryTime());
                lDetails.setCardId(userDetailsGather.getCardId());
                lDetails.setNation(userDetailsGather.getNation());
                lDetails.setEducationId(userDetailsGather.getEducationId());
                lDetails.setCreateTime(new Date());
                if(ilDetailsService.save(lDetails)){
                    LUser luser = new LUser();
                    luser.setDetailsId(lDetails.getDetailsId());
                    luser.setUserName(userDetailsGather.getUserName());
                    luser.setPassword(Md5Utils.hash(userDetailsGather.getPassword()));
                    luser.setMobile(userDetailsGather.getMobile());
                    luser.setEmail(userDetailsGather.getEmail());
                    luser.setStutes(userDetailsGather.getStutes());
                    luser.setCreateTime(new Date());
                    ilUserService.save(luser);
                }
            }
            return (CommonResult)ResultUtil.success(ResultEnum.SUCCESS,list);
        } catch (Exception e) {
            e.printStackTrace();
            return (CommonResult)ResultUtil.error(ResultEnum.ERROR);
        }
    }

    /**
     * 下载用户导入应用模板
     *
     * @return
     */
    @ApiOperation(value = "下载用户导入应用模板")
    @ResponseBody
    @GetMapping("/downloadUserExcel")
    public CommonResult<Object> downloadUserExcel(HttpServletRequest req, HttpServletResponse res) {
        try {
            //获取要下载的模板名称
            String fileName = "User.xls";
            //设置要下载的文件的名称
            res.setHeader("Content-disposition", "attachment;fileName=" + fileName);
            //通知客服文件的MIME类型
            res.setContentType("application/vnd.ms-excel;charset=UTF-8");
            //获取文件的路径
            String filePath = getClass().getResource("/templates/" + fileName).getPath();
            FileInputStream input = new FileInputStream(filePath);
            OutputStream out = res.getOutputStream();
            byte[] b = new byte[2048];
            int len;
            while ((len = input.read(b)) != -1) {
                out.write(b, 0, len);
            }
            //修正 Excel在“xxx.xlsx”中发现不可读取的内容。是否恢复此工作薄的内容？如果信任此工作簿的来源，请点击"是"
            res.setHeader("Content-Length", String.valueOf(input.getChannel().size()));
            input.close();
            return (CommonResult)ResultUtil.success(ResultEnum.SUCCESS);
        } catch (Exception ex) {
            ex.printStackTrace();
            return (CommonResult)ResultUtil.error(ResultEnum.ERROR);
        }
    }

    //导出
    @ApiOperation(value = "导出")
    @UserLoginToken
    @PostMapping("/exportUser")
    public CommonResult<Object>  exportUser(@RequestBody LUserDTO lUserDTO){
        try {
            QueryWrapper<UserDetailsGather> queryWrapper = new QueryWrapper<>();
            if(StringUtils.isNotEmpty(lUserDTO.getMobile()))
                queryWrapper.eq("mobile",lUserDTO.getMobile());
            if(StringUtils.isNotEmpty(lUserDTO.getUsername()))
                queryWrapper.like("user_name",lUserDTO.getUsername());
            if(StringUtils.isNotEmpty(lUserDTO.getStutes()))
                queryWrapper.eq("stutes",lUserDTO.getStutes());
            if(StringUtils.isNotEmpty(lUserDTO.getSex()))
                queryWrapper.eq("sex",lUserDTO.getSex());
            if(StringUtils.isNotEmpty(lUserDTO.getName()))
                queryWrapper.like("name",lUserDTO.getName());
            if(StringUtils.isNotEmpty(lUserDTO.getOrganizationId())) {
                QueryWrapper<LOrganization> lOrganizationQueryWrapper = new QueryWrapper<LOrganization>();
                lOrganizationQueryWrapper.eq("organization_type", "1");
                lOrganizationQueryWrapper.eq("organization_id", lUserDTO.getOrganizationId());
                List<LOrganization> lOrganizations = ilOrganizationService.queryLOrganizationAll(lOrganizationQueryWrapper);
                List<Integer> organs = new ArrayList<>();
                for (LOrganization lOrganization : lOrganizations) {
                    organs.add(lOrganization.getOrganizationId());
                }
                queryWrapper.in("organization_id", organs);
            }
            List<UserDetailsGather> lUsers = iUserDetailsGatherService.list(queryWrapper);
            for (UserDetailsGather userDetailsGather : lUsers) {
                LOrganization lOrganization = ilOrganizationService.getById(userDetailsGather.getOrganizationId());
                if(null != lOrganization){
                    userDetailsGather.setOrganizationName(lOrganization.getOrganizationName());
                }
            }
            ExcelUtils excelUtils = new ExcelUtils(UserDetailsGather.class);
            String fileName = excelUtils.exportExcel(lUsers,"用户");

            ApiAssert.isTrue(ErrorCodeEnum.FILE_ILLEGAL_FILENAME.overrideMsg(StringUtils.format("文件名称({})非法，不允许下载。 ", fileName)), FileUtils.isValidFilename(fileName));
            String filePrefix = FileUtils.getFilePrefix(fileName);
            String realFileName = fileName.split("_")[0] + "_" + DateUtils.dateTimeNow() + "." + filePrefix;
            String filePath = Crowns.getDownloadPath(fileName);
            response.setCharacterEncoding("utf-8");
            response.setContentType("multipart/form-data");
            response.setHeader("Content-Disposition",
                    "attachment;fileName=" + FileUtils.setFileDownloadHeader(request, realFileName));
            FileUtils.writeBytes(filePath, response.getOutputStream());
            FileUtils.deleteFile(filePath);
            // 返回
            return (CommonResult)ResultUtil.success(ResultEnum.SUCCESS);
        }catch (Exception e){
            e.printStackTrace();
            return (CommonResult)ResultUtil.error(ResultEnum.ERROR);
        }
    }
}

